home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_11 / 2n11059a < prev    next >
Text File  |  1991-09-27  |  5KB  |  159 lines

  1.  
  2. Listing 3.  ASCIIZ.ASM
  3.  
  4. code SEGMENT WORD PUBLIC 'CODE'
  5.  
  6.    ASSUME   CS:code,DS:code,ES:code
  7.  
  8.    ORG      00h
  9.  
  10. ; ========== Routine to Do Initialization and Test Run ==========
  11.  
  12. setup proc near       ; main procedure
  13.  
  14.    jmp  SHORT start   ; jump over data to code start point
  15.  
  16.    ALIGN 2
  17.    string      DB    "xxxxxxxxxxxxxxxxxxxxxxxxx"
  18.                DB    "xxxxxxxxxxxxxxxxxxxxxxxxx"
  19.                DB    "xxxxxxxxxxxxxxxxxxxxxxxxx"
  20.                DB    "xxxxxxxxxxxxxxxxxxxxxxxxx",0,0
  21.  
  22.    add_scasb   DW    scasb_version
  23.    get_length  DW    lodsw_version
  24.  
  25. start:
  26.  
  27.    push ds                    ; set up stack
  28.    sub  ax,ax                 ;    for return
  29.    push ax                    ;       to DOS
  30.  
  31.    push cs                    ; align cs
  32.    push cs                    ;    with ds
  33.    pop  ds                    ;       and es
  34.    pop  es                    ;
  35.  
  36.    call get_bus_width         ; routine to set address
  37.  
  38.    ;  ...............
  39.  
  40.    mov  cx,offset string      ; load pointer to string
  41.    call get_length            ; get length of string into CX
  42.  
  43.    ret
  44.  
  45. setup endp
  46.  
  47. ; ======= Routine to Determine Bus Width of Current Machine =====
  48.  
  49. get_bus_width  proc  near
  50.  
  51.    push  ds                   ; save data segment
  52.  
  53.    sti                        ; make sure interrupts are on
  54.    call  start_count          ; routine to start on next tick
  55. cmpsb_loop:
  56.    cmp   bl,ds:[046Ch]        ; next clock tick yet?
  57.    loopz cmpsb_loop           ; just loop if not
  58.    not   cx                   ; take ones complement
  59.    mov   ax,cx                ; store the value
  60.    call  start_count          ; routine to start on next tick
  61. cmpsw_loop:
  62.    cmp   bx,ds:[046Ch]        ; next clock tick yet?
  63.    loopz cmpsw_loop           ; just loop if not
  64.    not   cx                   ; take ones complement
  65.  
  66.    pop   ds                   ; restore data segment
  67.  
  68.    cmp   ax,cx                ; byte cmps equal word cmps?
  69.    jbe   init_quit            ; if so go with status quo
  70.    sub   ax,cx                ; else get the difference
  71.    sar   ax,1                 ; scale down to stay in range
  72.    sar   cx,1                 ; of registers
  73.    mov   bl,100               ; get the percent scaler
  74.    mul   bl                   ; scale the difference up
  75.    div   cx                   ; get the percentage
  76.    cmp   ax,2                 ; eight bit if the percentage
  77.    jbe   init_quit            ;   difference is two or more
  78.    mov   si,offset add_scasb  ; point to routine address
  79.    mov   di,offset get_length ; point to target address
  80.    movsw                      ; move the address into place
  81.       
  82. init_quit:
  83.  
  84.    ret
  85.  
  86. get_bus_width  endp
  87.  
  88. ; =========== Routine to Delay to Next Clock Interrupt =========
  89.  
  90. start_count  proc  near
  91.  
  92.    xor   cx,cx                   ; get a zero
  93.    mov   ds,cx                   ; point to BIOS area
  94.    dec   cx                      ; get 0FFFFh into CX
  95.    mov   bx,ds:[046Ch]           ; get the current clock tick
  96.  
  97. start_loop:
  98.    cmp   bx,ds:[046Ch]           ; next tick yet?
  99.    jz    start_loop              ; if not just loop
  100.    mov   bx,ds:[046Ch]           ; save tick value
  101.  
  102.    ret
  103.  
  104. start_count  endp
  105.  
  106. ; ============= SCASB Version of Get Length of ASCII ===========
  107.  
  108. scasb_version  proc  near
  109.  
  110.    cld                           ;  clear direction
  111.    mov   di,cx                   ;  load offset
  112.    mov   cx,0ffffh               ;  set counter
  113.    mov   al,0                    ;  load comparison value
  114.    repnz scasb                   ;  find the zero
  115.    not   cx                      ;  take ones complement
  116.    dec   cx                      ;  adjust length
  117.  
  118.    ret
  119.  
  120. scasb_version  endp
  121.  
  122. ; ============= LODSW Version of Get Length of ASCII ===========
  123.  
  124. lodsw_version  proc  near
  125.  
  126.    cld                           ;  clear direction
  127.    mov   si,cx                   ;  load offset
  128.  
  129. repeat:
  130.    REPT 10                       ;  block replicate macro
  131.    lodsw                         ;  load word from string
  132.    test  ah,al                   ;  zero yet?
  133.    jz    end_repeat              ;  if so exit and adjust
  134.    ENDM                          ;  end of macro
  135.  
  136.    lodsw                         ;  load word from string
  137.    test  ah,al                   ;  zero yet?
  138.    jnz   repeat                  ;  if not repeat
  139. end_repeat:
  140.    sub   si,cx                   ;  get unadjusted count
  141.    mov   cx,si                   ;  move it to destination
  142.    cmp   al,0                    ;  is lead byte zero?
  143.    jz    adj_two                 ;  if so adjust back two
  144.    dec   cx                      ;  else adjust back one
  145.    jmp   adj_end                 ;   then exit
  146. adj_two:
  147.    sub   cx,2                    ;  adjust back two
  148. adj_end:
  149.  
  150.    ret
  151.  
  152. lodsw_version  endp
  153.  
  154. ; ==============================================================
  155.  
  156. code ENDS   ; end of code segment
  157.  
  158.         end setup  ; end assembly
  159.